package com.ruyuan.rapid.core.context;

import com.ruyuan.rapid.common.config.Rule;
import io.netty.channel.ChannelHandlerContext;

import java.util.function.Consumer;

/**
 * 网关上下文接口
 */
public interface Context {

    //一个请求正在执行中
    int RUNNING = -1;

    //写回响应标记，标记当前请求需要写回
    int WRITTEN = 0;

    //当写回成功之后，设置该标记。ctx.writeAndFlush(response)
    int COMPLETED = 1;

    //表示网关请求完毕，彻底结束
    int TERMINATED = 2;

    /**
     * 设置上下文状态为RUNNING
     */
    void runned();

    /**
     * 设置上下文状态为WRITTEN
     */
    void writtened();

    /**
     * <B>方法名称：</B>completed<BR>
     * <B>概要说明：</B>设置上下文状态为写回结束<BR>
     *
     * @author JiFeng
     * @since 2021年12月9日 上午2:12:37
     */
    void completed();

    /**
     * <B>方法名称：</B>terminated<BR>
     * <B>概要说明：</B>设置上下文状态为最终结束<BR>
     *
     * @author JiFeng
     * @since 2021年12月9日 上午2:13:09
     */
    void terminated();

    boolean isRunning();

    boolean isWrittened();

    boolean isCompleted();

    boolean isTerminated();

    /**
     * 获取请求协议
     *
     * @return
     */
    String getProtocol();


    Rule getRule();

    RapidRequest getRequest();

    RapidResponse getResponse();

    /**
     * 设置响应对象
     *
     * @param response
     */
    void setResponse(Object response);

    /**
     * 获取异常
     *
     * @return
     */
    Throwable getThrowable();

    /**
     * 设置异常
     */
    void setThrowable(Throwable throwable);

    /**
     * 获取上下文参数，
     *
     * @param key
     * @param <T>
     * @return
     */
    <T> T getAttribute(AttributeKey<T> key);

    /**
     * 设置上下文参数
     * @param key
     * @param value
     * @param <T>
     */
    <T> T putAttribute(AttributeKey<T> key, T value);

    /**
     * 获取netty上下文
     * @return
     */
    ChannelHandlerContext getNettyCtx();

    /**
     * 是否保持连接
     * @return
     */
    boolean isKeepAlive();

    /**
     * 释放请求资源
     */
    void releaseRequest();

    /**
     *  设置回调函数
     */
    void completedCallback(Consumer<Context> consumer);

    /**
     * 执行回调函数
     */
    void invokeCompletedCallback();
}
